#include "Dialog.h"
#include <../../DebugTools/DebugTool.h>
#include <QtWidgets>
#include "ui_Dialog.h"

static inline QString versionAttribute() {
  return QStringLiteral("version");
}  // 版本   属性
static inline QString foldedAttribute() {
  return QStringLiteral("folded");
}  // 折叠   属性

static inline QString itemElement() {
  return QStringLiteral("item");
}  // item   名称
static inline QString codeElement() {
  return QStringLiteral("code");
}  // code   名称
static inline QString nameElement() {
  return QStringLiteral("name");
}  // name   名称
static inline QString typeElement() {
  return QStringLiteral("type");
}  // type   名称
static inline QString orientElement() {
  return QStringLiteral("direction");
}  // direction   名称

// 构造函数
Dialog::Dialog(QWidget* parent) : QDialog (parent)
, ui(new Ui::Dialog ) {

  ui->setupUi(this);
//  setAttribute (Qt::WA_DeleteOnClose);
//  setAttribute (Qt::WA_QuitOnClose);
  trees << ui->treeWidget_1;
  trees << ui->treeWidget_2;
  trees << ui->treeWidget_3;
  trees << ui->treeWidget_4;
  trees << ui->treeWidget_5;
  trees << ui->treeWidget_6;
  //  cout << trees;
  for (int i = 0; i < trees.count(); ++i) {
    trees.at(i)->clear();
    trees.at(i)->setColumnCount(4);
    trees.at(i)->setSelectionBehavior(QTreeView::SelectRows);
    trees.at(i)->setAlternatingRowColors(true);
    trees.at(i)->headerItem()->setText(0, "科目代码");
    trees.at(i)->headerItem()->setText(1, "科目名称");
    trees.at(i)->headerItem()->setText(2, "科目类别");
    trees.at(i)->headerItem()->setText(3, "余额方向");
    trees.at(i)->setEditTriggers (QTreeWidget::DoubleClicked);
    trees.at(i)->setIndentation (10);
//    cout << trees.at(i) << i;
    setSignSlots(trees.at(i));
  }


  setWindowFlag (Qt::WindowContextHelpButtonHint,false);
  setButtonState();// 设置按钮状态
//  cout << QDir::currentPath ();
  QFile file(QDir::currentPath () + "/kemuTree/会计科目.xml");
  file.open(QFile::ReadOnly);
  read(&file);
  file.close();

//  connect (this,&Widget::exit,&loop,&QEventLoop::quit );
}

Dialog::~Dialog() {
  delete ui;
}

void Dialog::load()
{
  QString fileName = QFileDialog::getOpenFileName(
      this, "打开会计科目文件", QDir::currentPath()+"/kemuTree/会计科目.xml", tr("XML Files (*.xml)"));
  if (fileName.isEmpty())
    return;

  QFile file(fileName);
  if (!file.open(QFile::ReadOnly | QFile::Text)) {
    QMessageBox::warning(
        this, "会计科目文件",
        tr("不能打开 %1:\n%2.")
            .arg(QDir::toNativeSeparators(fileName), file.errorString()));
  }
  foreach (auto tree, trees)
    tree->clear();
  bool ok = read(&file);
  Dout << ok;
}

bool Dialog::read(QIODevice* device) {
  xml.setDevice(device);

  if (xml.readNextStartElement()) {
    if (xml.name() == QStringLiteral("kemu") &&
        xml.attributes().value(versionAttribute()) == QLatin1String("1.0")) {
      readKeMu();
    } else {
      xml.raiseError(QObject::tr("The file is not an KeMu version 1.0 file."));
    }
  }
  return !xml.error();
}

bool Dialog::write(QIODevice* device) {
  xmlw.setAutoFormatting(true);
  xmlw.setDevice(device);
  xmlw.writeStartDocument();                         // 写开始文档
  xmlw.writeDTD(QStringLiteral("<!DOCTYPE kemu>"));  // 写DTD
  xmlw.writeStartElement(QStringLiteral("kemu"));    // 开始即根元素
  xmlw.writeAttribute(versionAttribute(), QStringLiteral("1.0"));  // 根元素属性
  for (int i = 0; i < trees.count(); ++i) {
    for (int j = 0; j < trees.at(i)->topLevelItemCount(); ++j)
      writeItem(trees.at(i)->topLevelItem(j));
  }
  xmlw.writeEndDocument();  // 写结束文档
  return true;
}

// 从kemu 这个元素节点开始读取
void Dialog::readKeMu() {
  Q_ASSERT(xml.isStartElement() && xml.name() == QLatin1String("kemu"));
  while (xml.readNextStartElement()) {
    if (xml.name() == itemElement())
      readItem(0);
    else if (xml.name() == codeElement())
      readCode(0);
    else if (xml.name() == nameElement())
      readName(0);
    else if (xml.name() == typeElement())
      readType(0);
    else if (xml.name() == orientElement())
      readOrient(0);
    else
      xml.skipCurrentElement();
  }
}

void Dialog::readItem(QTreeWidgetItem* item) {
  Q_ASSERT(xml.isStartElement() && xml.name() == itemElement());

  QTreeWidgetItem* childItem = createChildItem(item);
  bool folded =
      (xml.attributes().value(foldedAttribute()) != QLatin1String("no"));
  childItem->setExpanded(!folded);
  while (xml.readNextStartElement()) {
    if (xml.name() == itemElement())
      readItem(childItem);
    else if (xml.name() == codeElement())
      readCode(childItem);
    else if (xml.name() == nameElement())
      readName(childItem);
    else if (xml.name() == typeElement())
      readType(childItem);
    else if (xml.name() == orientElement())
      readOrient(childItem);
    else
      xml.skipCurrentElement();
  }
}

void Dialog::readCode(QTreeWidgetItem* item) {
  Q_ASSERT(xml.isStartElement() && xml.name() == codeElement());

  QString txt = xml.readElementText().trimmed();
  item->setText(0, txt);

  if (!item->treeWidget()) {
    int idx = txt.left(1).toInt() - 1;
    trees[idx]->addTopLevelItem(item);
  }
}

void Dialog::readName(QTreeWidgetItem* item) {
  Q_ASSERT(xml.isStartElement() && xml.name() == nameElement());
  QString txt = xml.readElementText().trimmed();
  item->setText(1, txt);
}

void Dialog::readType(QTreeWidgetItem* item) {
  Q_ASSERT(xml.isStartElement() && xml.name() == typeElement());
  QString txt = xml.readElementText().trimmed();
  item->setText(2, txt);
}

void Dialog::readOrient(QTreeWidgetItem* item) {
  Q_ASSERT(xml.isStartElement() && xml.name() == orientElement());
  QString txt = xml.readElementText().trimmed();
  item->setText(3, txt);
}



void Dialog::saveAs() {
  QString fileName = QFileDialog::getSaveFileName(
      this, "保存会计科目文件", QDir::currentPath()+"/会计科目.xml", "xml Files (*.xml)");
  if (fileName.isEmpty())
    return;

  QFile file(fileName);
  if (!file.open(QFile::WriteOnly | QFile::Text)) {
    QMessageBox::warning(
        this, tr("QXmlStream keumu"),
        tr("Cannot write file %1:\n%2.")
            .arg(QDir::toNativeSeparators(fileName), file.errorString()));
    return;
  }

  write(&file);
  file.close();
}

QStringList Dialog::getItemText()
{
  this->exec ();
  return list;
}

void Dialog::writeItem(const QTreeWidgetItem* item) {
  xmlw.writeStartElement(itemElement());
  xmlw.writeAttribute(foldedAttribute(), item->isExpanded() ? "yes" : "no");
  xmlw.writeTextElement(codeElement(), item->text(0));
  xmlw.writeTextElement(nameElement(), item->text(1));
  xmlw.writeTextElement(typeElement(), item->text(2));
  xmlw.writeTextElement(orientElement(), item->text(3));

  for (int i = 0; i < item->childCount(); ++i) {
    writeItem(item->child(i));
  }
  xmlw.writeEndElement();
}

QTreeWidgetItem* Dialog::createChildItem(QTreeWidgetItem* item) {
  QTreeWidgetItem* newItem = new QTreeWidgetItem(item);
  return newItem;
}

void Dialog::setSelectionMode(QTreeWidget* w) {
  if(canBeModified)
    w->setSelectionMode(QTreeWidget::ContiguousSelection);  // 连续选择
  else
    w->setSelectionMode(QTreeWidget::SingleSelection);  // 单个选择

  w->setSelectionBehavior(QTreeWidget::SelectRows);       // 选择行

}

void Dialog::on_btnXMLSave_clicked() {
  saveAs();
}

void Dialog::setDragAndDrop(QTreeWidget* w, bool dd) {
  w->setDragEnabled(dd);  // 启用拖动
  w->viewport()->setAcceptDrops(dd);  // viewport 接受放下动作，默认是复制操作
  w->setDropIndicatorShown(dd);                         // 设置放下指示
  if(dd)
    w->setDragDropMode(QTreeWidget::InternalMove);  // 内部 移动
  else
    w->setDragDropMode(QTreeWidget::NoDragDrop);  //   不拖放
}


void Dialog::on_btnItemModify_clicked() {
  canBeModified = true;
  for (int i = 0; i < trees.count(); ++i) {
    setDragAndDrop(trees.at(i));
    setSelectionMode(trees.at(i));
  }
  setButtonState();
}

void Dialog::on_btnXMLLoad_clicked() {
  load ();
}

void Dialog::onItemDoubleClicked(QTreeWidgetItem* item)
{
  if(canBeModified){
    item->setFlags (Qt::ItemIsEditable | item->flags () );
  } else {
    item->setFlags(item->flags() & ~Qt::ItemIsEditable);
    // item->setFlags((~Qt::ItemIsEditable) & (item->flags()));
    if (item->childCount() == 0) {
      list.clear();
      list << item->text(0) << item->text(1);
      while (item->parent()) {
        item = item->parent();
        list.insert(1, item->text(1));
      }
      close();
//      hide ();
    }
  }
}


void Dialog::setSignSlots(QTreeWidget* w) {
  connect(w, &QTreeWidget::itemDoubleClicked, this,
          &Dialog::onItemDoubleClicked);
}


void Dialog::on_btnOK_clicked()
{
  canBeModified = false;
  for (int i = 0; i < trees.count (); ++i) {
    setDragAndDrop (trees.at(i),canBeModified);
    setSelectionMode (trees.at(i));
  }
  setButtonState();
  QFile file("会计科目.xml");
  file.open(QFile::WriteOnly);
  write (&file);
  file.close();
}

void Dialog::setButtonState()
{
  ui->btnItemAdd->setEnabled (canBeModified);
  ui->btnItemDel->setEnabled (canBeModified);
  ui->btnOK->setEnabled (canBeModified);
  ui->btnXMLSave->setEnabled (canBeModified);
  ui->btnXMLLoad->setEnabled (!canBeModified);
  ui->btnItemModify->setEnabled (!canBeModified);
}

void Dialog::on_btnItemAdd_clicked()
{
  int idx = ui->tabWidget->currentIndex ();
  QTreeWidget *tree = trees.at (idx);
  QTreeWidgetItem *item = tree->currentItem ();
  QTreeWidgetItem *newitem = new QTreeWidgetItem(*item);
  newitem->setForeground (0,Qt::red);
  QTreeWidgetItem *parent = item->parent ();
  if(parent){
    idx = parent->indexOfChild (item);
    parent->insertChild (idx,newitem);
  }
  else {
    idx = tree->indexOfTopLevelItem (item);
    tree->insertTopLevelItem (idx,newitem);
  }
}

void Dialog::on_btnItemDel_clicked()
{
  int idx = ui->tabWidget->currentIndex ();
  QTreeWidget *tree = trees.at (idx);

  QList<QTreeWidgetItem *> items = tree->selectedItems();

  for (int i = 0; i < items.count (); ++i) {
    QTreeWidgetItem *item = tree->currentItem ();

    if(!item)
      return;

    QTreeWidgetItem *parent = item->parent ();
    if(parent){
      parent->removeChild (item);
      delete item;
      item = 0;
    }
    else {
      idx = tree->indexOfTopLevelItem (item);
      tree->takeTopLevelItem (idx);
      delete item;
      item = 0;
    }
  }
}
